"""
Controller Mock Server - Receive events from Coordinator
"""

import sys
import threading
import time
from datetime import datetime, timezone
from fastapi import FastAPI, HTTPException
from fastapi.responses import JSONResponse
from pydantic import BaseModel, Field

# Configure logging
import logging
logger = logging.getLogger(__name__)

# Request models
class TerminateInstanceRequest(BaseModel):
    instance_id: int = Field(..., description="Instance ID to terminate")
    reason: str = Field(..., description="Reason for termination")

class ReportAlarmRequest(BaseModel):
    alarm_type: str = Field(..., description="Type of alarm")
    message: str = Field(..., description="Alarm message")
    severity: str = Field(..., description="Alarm severity level")

# Controller state management
class ControllerState:
    """Controller state management for tracking requests"""
    
    def __init__(self):
        self.terminated_instances: list[dict] = []
        self.alarms: list[dict] = []
        self._lock = threading.Lock()
        self.start_time = datetime.now(timezone.utc)
    
    def terminate_instance(self, instance_id: int, reason: str) -> bool:
        """Record instance termination request"""
        with self._lock:
            termination_record = {
                "instance_id": instance_id,
                "reason": reason,
                "timestamp": datetime.now(timezone.utc).isoformat(),
                "status": "terminated"
            }
            self.terminated_instances.append(termination_record)
            logger.info(f"Instance termination recorded: ID={instance_id}, Reason={reason}")
            return True
    
    def report_alarm(self, alarm_type: str, message: str, severity: str) -> bool:
        """Record alarm report"""
        with self._lock:
            alarm_record = {
                "alarm_type": alarm_type,
                "message": message,
                "severity": severity,
                "timestamp": datetime.now(timezone.utc).isoformat(),
                "status": "reported"
            }
            self.alarms.append(alarm_record)
            logger.info(f"Alarm reported: Type={alarm_type}, Severity={severity}, Message={message}")
            return True
    
    def get_status(self) -> dict:
        """Get current controller state"""
        with self._lock:
            return {
                "service": "mock_controller",
                "uptime_seconds": (datetime.now(timezone.utc) - self.start_time).total_seconds(),
                "total_terminations": len(self.terminated_instances),
                "total_alarms": len(self.alarms),
                "recent_terminations": self.terminated_instances[-10:],  # Last 10 records
                "recent_alarms": self.alarms[-10:]  # Last 10 records
            }
    
    def clear_data(self):
        """Clear all recorded data (for testing)"""
        with self._lock:
            self.terminated_instances.clear()
            self.alarms.clear()
            logger.info("Controller state data cleared")

# Global controller state
controller_state = ControllerState()

# FastAPI application
app = FastAPI(
    title="Controller Mock Server",
    description="Mock Controller service for testing Coordinator components",
    version="1.0.0"
)

@app.post("/controller/terminate_instance")
async def terminate_instance(request: TerminateInstanceRequest):
    """
    Terminate instance endpoint
    This endpoint simulates the controller's instance termination functionality
    """
    try:
        logger.info(f"Received terminate instance request: ID={request.instance_id}, Reason={request.reason}")
        
        # Record the termination request
        success = controller_state.terminate_instance(request.instance_id, request.reason)
        
        if success:
            # Simulate processing time
            time.sleep(0.1)
            
            return JSONResponse(
                status_code=200,
                content={
                    "status": "success",
                    "message": f"Instance {request.instance_id} termination request accepted",
                    "instance_id": request.instance_id,
                    "timestamp": datetime.now(timezone.utc).isoformat()
                }
            )
        else:
            raise HTTPException(status_code=500, detail="Failed to process termination request")
            
    except Exception as e:
        logger.error(f"Error processing terminate instance request: {e}")
        raise HTTPException(status_code=500, detail=f"Internal server error: {str(e)}")

@app.post("/controller/report_alarm")
async def report_alarm(request: ReportAlarmRequest):
    """
    Report alarm endpoint
    This endpoint simulates the controller's alarm reporting functionality
    """
    try:
        logger.info(f"Received alarm report: Type={request.alarm_type}, Severity={request.severity}")
        
        # Record the alarm
        success = controller_state.report_alarm(
            request.alarm_type, 
            request.message, 
            request.severity
        )
        
        if success:
            # Simulate processing time
            time.sleep(0.05)
            
            return JSONResponse(
                status_code=200,
                content={
                    "status": "success",
                    "message": "Alarm report accepted",
                    "alarm_type": request.alarm_type,
                    "severity": request.severity,
                    "timestamp": datetime.now(timezone.utc).isoformat()
                }
            )
        else:
            raise HTTPException(status_code=500, detail="Failed to process alarm report")
            
    except Exception as e:
        logger.error(f"Error processing alarm report: {e}")
        raise HTTPException(status_code=500, detail=f"Internal server error: {str(e)}")

@app.get("/controller/status")
async def get_controller_status():
    """
    Get controller status
    Returns the current state of the mock controller including recent requests
    """
    try:
        status = controller_state.get_status()
        return JSONResponse(
            status_code=200,
            content=status
        )
    except Exception as e:
        logger.error(f"Error getting controller status: {e}")
        raise HTTPException(status_code=500, detail=f"Status error: {str(e)}")

@app.post("/controller/clear")
async def clear_controller_data():
    """
    Clear controller data
    This endpoint clears all recorded data (useful for testing)
    """
    try:
        controller_state.clear_data()
        return JSONResponse(
            status_code=200,
            content={
                "status": "success",
                "message": "Controller data cleared successfully"
            }
        )
    except Exception as e:
        logger.error(f"Error clearing controller data: {e}")
        raise HTTPException(status_code=500, detail=f"Clear error: {str(e)}")

@app.get("/health")
async def health_check():
    """
    Health check endpoint
    Basic health check to verify the service is running
    """
    return JSONResponse(
        status_code=200,
        content={
            "status": "healthy",
            "service": "mock_controller",
            "timestamp": datetime.now(timezone.utc).isoformat()
        }
    )

@app.get("/")
async def root():
    """
    Root endpoint
    Returns API information and available endpoints
    """
    return {
        "service": "Controller Mock Server",
        "version": "1.0.0",
        "endpoints": {
            "POST /controller/terminate_instance": "Terminate an instance",
            "POST /controller/report_alarm": "Report an alarm",
            "GET /controller/status": "Get controller status",
            "POST /controller/clear": "Clear controller data",
            "GET /health": "Health check"
        }
    }

def main(port):
    """Main function - Start Controller Mock Server"""
    import uvicorn
    
    logger.info(f"Starting Controller Mock Server on port {port}...")
    uvicorn.run(
        app,
        host="localhost",
        port=port,
        log_level="info"
    )

if __name__ == "__main__":
    if len(sys.argv) != 2:
        print("Usage: python mock_controller.py <port>")
        sys.exit(1)
    
    main(int(sys.argv[1]))